package com.yfp.device.controller;


import com.yfp.common.core.utils.WeixinRobotSender;
import com.yfp.common.log.annotation.Log;
import com.yfp.common.log.enums.BusinessType;
import com.yfp.device.domain.*;
import com.yfp.device.domain.dto.*;
import com.yfp.device.domain.vo.ForeshowVo;
import com.yfp.device.domain.vo.MachineDebugLogVo;
import com.yfp.device.domain.vo.ReplenishVo;
import com.yfp.device.service.*;
import com.yfp.device.service.impl.ApkVersionServiceImpl;
import io.swagger.annotations.ApiParam;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ApplicationContext;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * 设备管理表控制层
 *
 * 
 * @since 2023-12-11 17:38:53
 */
@Tag(name = "设备接口")
@RestController
@Validated
@RequestMapping("")
@RefreshScope
public class DeviceController {

    private static final Logger log = LoggerFactory.getLogger(DeviceController.class);
    private final ApkVersionServiceImpl apkVersionService;

    private final MachineService machineService;

    private final AdService adService;

    private final UserService userService;

    private final MachineLogService machineLogService;

    private final OrderService orderService;

    @Autowired
    private ApplicationContext applicationContext;

    public DeviceController(ApkVersionServiceImpl apkVersionService, MachineService machineService, AdService adService, UserService userService, MachineLogService machineLogService, OrderService orderService) {
        this.apkVersionService = apkVersionService;
        this.machineService = machineService;
        this.adService = adService;
        this.userService = userService;
        this.machineLogService = machineLogService;
        this.orderService = orderService;
    }

    /**
     * 补货员角色id
     */
    @Value("${qlf-custom-param.rep-role-id}")
    private String repRoleId;

    /**
     * 登录
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "登录-自测通过")
    @PostMapping("login")
    public R<?> login(@RequestBody LoginRequest request) {
        return userService.userLogin(request.getUserName(), request.getPassword(), request.getMachineSn());
    }

    /**
     * 获取最新安装包
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "获取最新安装包-自测通过")
    @PostMapping("lastApk")
    public R<ApkVersionResponse> getLastApkVersion(@RequestBody ApkVersionRequest request) {
        return apkVersionService.getLeastApkVersion(request.getMachineSn());
    }

    /**
     * 更新设备温度
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "更新设备温度-自测通过")
    @PostMapping("updateTemp")
    public R<?> updateTemp(@RequestBody UpdateTempRequest request) {
        return machineService.updateTemperature(request.getMachineSn(), request.getTemperature());
    }

    /**
     * 上传设备日志文件
     *
     * @param machineSn 机器编号
     * @param logFile   日志文件
     * @return 响应体
     */
    @Deprecated
    @Operation(summary = "上传设备日志文件-自测通过", parameters = {@Parameter(name = "machineSn", description = "机器编号", required = true, example = "1737326530549387264")})
    @PostMapping("uploadLogFile")
    public R<?> uploadLogFile(@RequestParam(value = "machineSn") String machineSn, MultipartFile logFile) {
        return machineService.uploadLogFile(machineSn, logFile);
    }


    /**
     * 查询日志文件
     *
     * @param request 请求体
     * @return 响应体
     */
    @Deprecated
    @Operation(summary = "查询日志文件")
    @PostMapping("qryLogFiles")
    public R<QryLogFilesResponse> qryLogFiles(@RequestBody QryLogFilesRequest request) {
        return machineService.qryLogFiles(request);
    }

    /**
     * 上传埋点日志文件
     *
     * @param machineSn      机器编号
     * @param type           埋点日志类型  1：登录日志 2：操作日志 3：崩溃日志  4：销售日志
     * @param eventTrackFile 埋点日志文件
     * @return 响应体
     */
    @Operation(summary = "上传埋点日志文件-自测通过", parameters = {@Parameter(name = "machineSn", description = "机器编号", required = true, example = "1737326530549387264"), @Parameter(name = "type", description = "埋点日志类型  1：登录日志 2：操作日志 3：崩溃日志  4：销售日志", required = true, example = "1")})
    @PostMapping("uploadEventTrackFile")
    public R<?> uploadEventTrackFile(@RequestParam(value = "machineSn") String machineSn, @RequestParam(value = "type") Integer type, MultipartFile eventTrackFile) {
        return machineService.uploadEventTrackFile(machineSn, type, eventTrackFile);
    }

    /**
     * 上传机器日志
     *
     * @param request 请求体
     * @return 响应体
     */
    @Deprecated
    @Operation(summary = "上传机器日志")
    @PostMapping("uploadMachineLog")
    public R<?> uploadMachineLog(@RequestBody UploadMachineLogRequest request) {
        return switch (request.getLogType()) {
            // 登录日志
            case "1" -> machineLogService.uploadMachineLoginLog(request.getMachineSn(), request.getMachineLoginLogVo());
            // 崩溃日志
            case "2" -> machineLogService.uploadMachineDownLog(request.getMachineSn(), request.getMachineDownLogVo());
            // 操作日志
            case "3" -> machineLogService.uploadMachineOpLog(request.getMachineSn(), request.getMachineOpLogVo());
            default -> R.fail("日志类型不正确");
        };
    }

    /**
     * 更新设备经纬度
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "更新设备经纬度-自测通过")
    @PostMapping("updateLatAndLon")
    public R<?> updateLatAndLon(@RequestBody UpdateLatAndLonRequest request) {
        return machineService.updateLatAndLon(request.getMachineSn(), request.getLongitude(), request.getLatitude());
    }

    /**
     * 上报设备部件状态
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "上报设备部件状态-自测通过")
    @PostMapping("reportComponent")
    public R<?> reportComponent(@RequestBody ReportComponentRequest request) {
        return machineService.reportComponent(request.getMachineSn(), request.getCheckTypeEnum(), request.getIsWork());
    }

    /**
     * 机器广告设置反馈
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "机器广告设置反馈")
    @PostMapping("machineAdFeedback")
    public R<?> machineAdFeedback(@RequestBody MachineAdFeedbackRequest request) {
        return adService.machineAdFeedback(request.getRecordNo(), request.getSetStatus());
    }

    /**
     * 机器版本反馈
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "机器版本反馈")
    @PostMapping("machineApkFeedback")
    public R<?> machineApkFeedback(@RequestBody MachineApkFeedbackRequest request) {
        return apkVersionService.machineApkFeedback(request);
    }

    /**
     * 报损
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "报损-自测通过")
    @PostMapping("damageReport")
    public R<?> damageReport(@RequestBody DamageReportRequest request) {
        return machineService.damageReport(request.getMachineSn(), request.getUserName(), request.getMachineRoads());
    }

    /**
     * 同步货道库存
     *
     * @param request 请求体
     * @return 响应体
     */
    @Deprecated
    @Operation(summary = "同步货道库存-自测通过")
    @PostMapping("syncRoadInventory")
    public R<?> syncRoadInventory(@RequestBody SyncRoadInventoryRequest request) {
        return machineService.syncRoadInventory(request.getMachineSn(), request.getUserName(), request.getMachineRoads());
    }

    /**
     * 同步告警信息
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "同步告警信息")
    @PostMapping("syncWarn")
    public R<?> syncWarn(@RequestBody SyncWarnRequest request) {
        return machineService.syncWarn(request);
    }

    /**
     * 故障上报
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "故障上报-自测通过")
    @PostMapping("reportError")
    public R<?> reportError(@RequestBody ReportErrorRequest request) {
        return machineService.reportError(request);
    }

    /**
     * 故障修复
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "故障修复-自测通过")
    @PostMapping("repairError")
    public R<?> repairError(@RequestBody RepairErrorRequest request) {
        return machineService.repairError(request.getMachineSn(), request.getErrCode(), request.getRepairTime());
    }

    /**
     * 上报VMC连接状态
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "上报VMC连接状态-自测通过")
    @PostMapping("reportVMCStatus")
    public R<?> reportVMCStatus(@RequestBody ReportVMCStatusRequest request) {
        return machineService.reportVMCStatus(request.getMachineSn(), request.getVmcStatus());
    }

    /**
     * 设备在线
     *
     * @param machineSn 机器编号
     * @return 响应体
     */
    @Operation(summary = "设备在线-自测通过", parameters = {@Parameter(name = "machineSn", description = "机器编号", required = true, example = "1737326530549387264")})
    @PostMapping("online")
    public R<?> online(@RequestParam(value = "machineSn") String machineSn) {
        return machineService.online(machineSn);
    }

    /**
     * 更新广告状态
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "更新广告状态-自测通过")
    @PostMapping("updateAdStatus")
    public R<?> updateAdStatus(@RequestBody UpdateAdStatusRequest request) {
        return machineService.updateAdStatus(request.getMachineSn(), request.getAdId(), request.getPlayStatus());
    }

    /**
     * 查询机器编号
     *
     * @param machineSn 设备id
     * @return 机器编号
     */
    @Operation(summary = "查询机器编号", parameters = {@Parameter(name = "machineSn", description = "设备id（雪花算法）", required = true, example = "998748454575245")})
    @PostMapping("qryMachineSerial")
    public R<String> qryMachineSerial(@RequestParam(value = "machineSn") String machineSn) {
        return machineService.qryMachineSerial(machineSn);
    }

    /**
     * 查询设备id
     *
     * @param machineSerial 机器编号
     * @return 设备id
     */
    @Operation(summary = "查询设备id", parameters = {@Parameter(name = "machineSerial", description = "设备id（雪花算法）", required = true, example = "202401050100000002")})
    @PostMapping("qryMachineSn")
    public R<String> qryMachineSn(@RequestParam(value = "machineSerial") String machineSerial) {
        return machineService.qryMachineSn(machineSerial);
    }

    /**
     * 查询设备营运时间
     *
     * @param machineSn 机器编号
     * @return 响应体
     */
    @Operation(summary = "查询设备营运时间", parameters = {@Parameter(name = "machineSn", description = "机器编号", required = true, example = "998748454575245")})
    @PostMapping("qryMachineOpTime")
    public R<?> qryMachineOpTime(@RequestParam(value = "machineSn") String machineSn) {
        return machineService.qryMachineOpTime(machineSn);
    }

    /**
     * 检查机器编号
     *
     * @param machineSn 机器编号
     * @return 响应体
     */
    @Operation(summary = "检查机器编号", parameters = {@Parameter(name = "machineSn", description = "机器编号", required = true, example = "998748454575245")})
    @PostMapping("checkMachineSn")
    public R<?> checkMachineSn(@RequestParam(value = "machineSn") String machineSn) {
        return machineService.checkMachineSn(machineSn);
    }

    /**
     * 同步广告
     *
     * @param machineSn 机器编号
     * @return 响应体
     */
    @Operation(summary = "同步广告", parameters = {@Parameter(name = "machineSn", description = "机器编号", required = true, example = "998748454575245")})
    @PostMapping("syncMachineAd")
    public R<SyncMachineAdResponse> syncMachineAd(@RequestParam(value = "machineSn") String machineSn) {
        return adService.syncMachineAd(machineSn);
    }

    /**
     * 更新运营状态
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "更新运营状态")
    @PostMapping("updateOperationStatus")
    public R<?> updateOperationStatus(@RequestBody UpdateOperationStatusRequest request) {
        return machineService.updateOperationStatus(request.getMachineSn(), request.getOperationStatus());
    }

    /**
     * 获取机器信息
     *
     * @param machineSn 机器编号
     * @return 响应体
     */
    @Operation(summary = "获取机器信息-自测通过")
    @PostMapping("qryMachineInfo")
    public R<?> qryMachineInfo(@RequestParam(value = "machineSn") String machineSn) {
        return machineService.qryMachineInfo(machineSn);
    }

    /**
     * 上传工单
     *
     * @param request 请求体
     * @return 响应体
     */
    @Operation(summary = "上传工单")
    @PostMapping("uploadWorkOrder")
    public R<?> uploadWorkOrder(@RequestBody UploadWorkOrderRequest request) {
        R<?> r = orderService.uploadWorkOrder(request);
        try {
            orderService.wxNotify(request);
        } catch (Exception e) {
            log.info("微信通知失败：" + e.getMessage());
        }
        return r;
    }

    /**
     * 上传调试日志
     *
     * @param machineDebugLogVo 请求体
     * @return 响应体
     */
    @Deprecated
    @Operation(summary = "上传调试日志")
    @PostMapping("uploadDebugLog")
    public R<?> uploadDebugLog(@RequestBody MachineDebugLogVo machineDebugLogVo) {
        return machineService.uploadDebugLog(machineDebugLogVo);
    }

    /**
     * 查询调试日志
     *
     * @param request 请求体
     * @return 响应体
     */
    @Deprecated
    @Operation(summary = "查询调试日志")
    @PostMapping("qryDebugLogs")
    public R<QryDebugLogsResponse> qryDebugLogs(@RequestBody QryDebugLogsRequest request) {
        return machineService.qryDebugLogs(request);
    }

    /**
     * 同步货道信息
     *
     * @param machineSn 机器编号
     * @return 响应体
     */
    @Operation(summary = "同步货道信息")
    @PostMapping("syncMachineRoad")
    public R<SyncMachineRoadResponse> syncMachineRoad(@RequestParam(value = "machineSn") String machineSn) {
        return machineService.syncMachineRoad(machineSn);
    }

    /**
     * 获取设备库存报警阈值
     *
     * @param machineSn 机器编号
     * @return 响应体
     */
    @Operation(summary = "获取设备库存报警阈值")
    @PostMapping("qryMachineThreshold")
    public R<QryMachineThresholdResponse> qryMachineThreshold(@RequestParam(value = "machineSn") String machineSn) {
        return machineService.qryMachineThreshold(machineSn);
    }


    /**
     * 上报暂存柜空余数量
     *
     * @param
     * @return
     */
    @Operation(summary = "上报设备暂存柜数量")
    @PostMapping("/temporary_lockers")
    public R<String> reportTemporaryLockers(@ApiParam(value = "设备id") @NotNull(message = "设备id不能为空") @RequestParam String machineId, @ApiParam(value = "数量") @NotNull(message = "数量不能为空") @RequestParam String count) {
        return machineService.reportTemporaryLockers(machineId, count);
    }


    /**
     * 设备上报收到立即制作信息
     *
     * @param
     * @return
     */
    @Operation(summary = "设备上报收到立即制作信息")
    @PutMapping("/applet/report/package_status")
    public R<String> reportPackageStatus(@RequestBody PackageStatus packageStatus) {
        return machineService.reportPackageStatus(packageStatus);
    }

    /**
     * 获取线上库存信息
     *
     * @return
     */
    @Operation(summary = "获取线上库存信息")
    @GetMapping("/action/combo_stock/info")
    public R<List<DeviceCurrentComboStock>> getDeviceComboStockInfo() {
        return machineService.getDeviceComboStockInfo();
    }


    /**
     * 获取明日预告
     *
     * @return
     */
    @Operation(summary = "获取明日预告")
    @GetMapping("/combo/forecast/list")
    public R<List<ForeshowVo>> deviceComboForecastList() {
        return machineService.deviceComboForecastList();
    }


    /**
     * 获取投放计划
     *
     * @return
     */
    @Operation(summary = "获取投放计划")
    @GetMapping("/action/placement_plan/sync/preview")
    public R<List<ReplenishVo>> devicePlacementPlanSyncPreview() {
        return machineService.devicePlacementPlanSyncPreview();
    }


    /**
     * 提交投放计划
     *
     * @return
     */
    @Operation(summary = "提交投放计划")
    @Log(title = "设备-提交投放计划", businessType = BusinessType.UPDATE)
    @GetMapping("/action/placement_plan/sync")
    public R<List<ReplenishVo>> devicePlacementPlanSync() {
        return machineService.devicePlacementPlanSync();
    }


    /**
     * 修改库存
     *
     * @return
     */
    @Operation(summary = "修改库存")
    @Log(title = "设备-修改库存", businessType = BusinessType.UPDATE)
    @PutMapping("/action/combo_stock/sync")
    public R<?> deviceComboStockSync(@RequestBody List<DeviceCurrentComboPlanRoad> dccprs) {
        return machineService.deviceComboStockSync(dccprs);
    }


    /**
     * 立即制作套餐
     *
     * @param makePackageDTO
     * @return
     */
//    @Operation(summary = "立即制作套餐")
//    @PostMapping("/action/package/make")
//    public R<?> makePackage(@RequestBody MakePackageDTO makePackageDTO) {
//        return machineService.makePackage(makePackageDTO);
//    }
    @Operation(summary = "定时任务企业微信发送报警信息")
    @PostMapping("/sendWeiXin")
    public R<?> sendWeiXin() {
        machineService.sendWeiXin();
        return R.ok();
    }

    @Operation(summary = "任务企业微信发送报警信息")
    @PostMapping("/sendExceptionRemind")
    public R<?> sendExceptionRemind(@RequestParam(value = "exceptionMsg") String exceptionMsg) {
        WeixinRobotSender.sendTextMessage(exceptionMsg, applicationContext);
        return R.ok();
    }

    @Operation(summary = "异常订单修改库存")
    @PostMapping("/updateByMachineIdAndRoadNum")
    public R updateByMachineIdAndRoadNum(@RequestBody UpdateByMachineIdAndRoadNumDTO updateByMachineIdAndRoadNumDTO) {
        machineService.updateByMachineIdAndRoadNum(updateByMachineIdAndRoadNumDTO);
        return R.ok();
    }


}

